home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / bsddb / dbshelve.py < prev    next >
Text File  |  2008-10-05  |  9KB  |  302 lines

  1. #! /usr/bin/python2.5
  2. #------------------------------------------------------------------------
  3. #           Copyright (c) 1997-2001 by Total Control Software
  4. #                         All Rights Reserved
  5. #------------------------------------------------------------------------
  6. #
  7. # Module Name:  dbShelve.py
  8. #
  9. # Description:  A reimplementation of the standard shelve.py that
  10. #               forces the use of cPickle, and DB.
  11. #
  12. # Creation Date:    11/3/97 3:39:04PM
  13. #
  14. # License:      This is free software.  You may use this software for any
  15. #               purpose including modification/redistribution, so long as
  16. #               this header remains intact and that you do not claim any
  17. #               rights of ownership or authorship of this software.  This
  18. #               software has been tested, but no warranty is expressed or
  19. #               implied.
  20. #
  21. # 13-Dec-2000:  Updated to be used with the new bsddb3 package.
  22. #               Added DBShelfCursor class.
  23. #
  24. #------------------------------------------------------------------------
  25.  
  26. """Manage shelves of pickled objects using bsddb database files for the
  27. storage.
  28. """
  29.  
  30. #------------------------------------------------------------------------
  31.  
  32. import cPickle
  33. try:
  34.     from UserDict import DictMixin
  35. except ImportError:
  36.     # DictMixin is new in Python 2.3
  37.     class DictMixin: pass
  38. import db
  39.  
  40. #------------------------------------------------------------------------
  41.  
  42.  
  43. def open(filename, flags=db.DB_CREATE, mode=0660, filetype=db.DB_HASH,
  44.          dbenv=None, dbname=None):
  45.     """
  46.     A simple factory function for compatibility with the standard
  47.     shleve.py module.  It can be used like this, where key is a string
  48.     and data is a pickleable object:
  49.  
  50.         from bsddb import dbshelve
  51.         db = dbshelve.open(filename)
  52.  
  53.         db[key] = data
  54.  
  55.         db.close()
  56.     """
  57.     if type(flags) == type(''):
  58.         sflag = flags
  59.         if sflag == 'r':
  60.             flags = db.DB_RDONLY
  61.         elif sflag == 'rw':
  62.             flags = 0
  63.         elif sflag == 'w':
  64.             flags =  db.DB_CREATE
  65.         elif sflag == 'c':
  66.             flags =  db.DB_CREATE
  67.         elif sflag == 'n':
  68.             flags = db.DB_TRUNCATE | db.DB_CREATE
  69.         else:
  70.             raise db.DBError, "flags should be one of 'r', 'w', 'c' or 'n' or use the bsddb.db.DB_* flags"
  71.  
  72.     d = DBShelf(dbenv)
  73.     d.open(filename, dbname, filetype, flags, mode)
  74.     return d
  75.  
  76. #---------------------------------------------------------------------------
  77.  
  78. class DBShelveError(db.DBError): pass
  79.  
  80.  
  81. class DBShelf(DictMixin):
  82.     """A shelf to hold pickled objects, built upon a bsddb DB object.  It
  83.     automatically pickles/unpickles data objects going to/from the DB.
  84.     """
  85.     def __init__(self, dbenv=None):
  86.         self.db = db.DB(dbenv)
  87.         self.binary = 1
  88.  
  89.  
  90.     def __del__(self):
  91.         self.close()
  92.  
  93.  
  94.     def __getattr__(self, name):
  95.         """Many methods we can just pass through to the DB object.
  96.         (See below)
  97.         """
  98.         return getattr(self.db, name)
  99.  
  100.  
  101.     #-----------------------------------
  102.     # Dictionary access methods
  103.  
  104.     def __len__(self):
  105.         return len(self.db)
  106.  
  107.  
  108.     def __getitem__(self, key):
  109.         data = self.db[key]
  110.         return cPickle.loads(data)
  111.  
  112.  
  113.     def __setitem__(self, key, value):
  114.         data = cPickle.dumps(value, self.binary)
  115.         self.db[key] = data
  116.  
  117.  
  118.     def __delitem__(self, key):
  119.         del self.db[key]
  120.  
  121.  
  122.     def keys(self, txn=None):
  123.         if txn != None:
  124.             return self.db.keys(txn)
  125.         else:
  126.             return self.db.keys()
  127.  
  128.  
  129.     def items(self, txn=None):
  130.         if txn != None:
  131.             items = self.db.items(txn)
  132.         else:
  133.             items = self.db.items()
  134.         newitems = []
  135.  
  136.         for k, v in items:
  137.             newitems.append( (k, cPickle.loads(v)) )
  138.         return newitems
  139.  
  140.     def values(self, txn=None):
  141.         if txn != None:
  142.             values = self.db.values(txn)
  143.         else:
  144.             values = self.db.values()
  145.  
  146.         return map(cPickle.loads, values)
  147.  
  148.     #-----------------------------------
  149.     # Other methods
  150.  
  151.     def __append(self, value, txn=None):
  152.         data = cPickle.dumps(value, self.binary)
  153.         return self.db.append(data, txn)
  154.  
  155.     def append(self, value, txn=None):
  156.         if self.get_type() == db.DB_RECNO:
  157.             return self.__append(value, txn=txn)
  158.         raise DBShelveError, "append() only supported when dbshelve opened with filetype=dbshelve.db.DB_RECNO"
  159.  
  160.  
  161.     def associate(self, secondaryDB, callback, flags=0):
  162.         def _shelf_callback(priKey, priData, realCallback=callback):
  163.             data = cPickle.loads(priData)
  164.             return realCallback(priKey, data)
  165.         return self.db.associate(secondaryDB, _shelf_callback, flags)
  166.  
  167.  
  168.     #def get(self, key, default=None, txn=None, flags=0):
  169.     def get(self, *args, **kw):
  170.         # We do it with *args and **kw so if the default value wasn't
  171.         # given nothing is passed to the extension module.  That way
  172.         # an exception can be raised if set_get_returns_none is turned
  173.         # off.
  174.         data = apply(self.db.get, args, kw)
  175.         try:
  176.             return cPickle.loads(data)
  177.         except (TypeError, cPickle.UnpicklingError):
  178.             return data  # we may be getting the default value, or None,
  179.                          # so it doesn't need unpickled.
  180.  
  181.     def get_both(self, key, value, txn=None, flags=0):
  182.         data = cPickle.dumps(value, self.binary)
  183.         data = self.db.get(key, data, txn, flags)
  184.         return cPickle.loads(data)
  185.  
  186.  
  187.     def cursor(self, txn=None, flags=0):
  188.         c = DBShelfCursor(self.db.cursor(txn, flags))
  189.         c.binary = self.binary
  190.         return c
  191.  
  192.  
  193.     def put(self, key, value, txn=None, flags=0):
  194.         data = cPickle.dumps(value, self.binary)
  195.         return self.db.put(key, data, txn, flags)
  196.  
  197.  
  198.     def join(self, cursorList, flags=0):
  199.         raise NotImplementedError
  200.  
  201.  
  202.     #----------------------------------------------
  203.     # Methods allowed to pass-through to self.db
  204.     #
  205.     #    close,  delete, fd, get_byteswapped, get_type, has_key,
  206.     #    key_range, open, remove, rename, stat, sync,
  207.     #    upgrade, verify, and all set_* methods.
  208.  
  209.  
  210. #---------------------------------------------------------------------------
  211.  
  212. class DBShelfCursor:
  213.     """
  214.     """
  215.     def __init__(self, cursor):
  216.         self.dbc = cursor
  217.  
  218.     def __del__(self):
  219.         self.close()
  220.  
  221.  
  222.     def __getattr__(self, name):
  223.         """Some methods we can just pass through to the cursor object.  (See below)"""
  224.         return getattr(self.dbc, name)
  225.  
  226.  
  227.     #----------------------------------------------
  228.  
  229.     def dup(self, flags=0):
  230.         return DBShelfCursor(self.dbc.dup(flags))
  231.  
  232.  
  233.     def put(self, key, value, flags=0):
  234.         data = cPickle.dumps(value, self.binary)
  235.         return self.dbc.put(key, data, flags)
  236.  
  237.  
  238.     def get(self, *args):
  239.         count = len(args)  # a method overloading hack
  240.         method = getattr(self, 'get_%d' % count)
  241.         apply(method, args)
  242.  
  243.     def get_1(self, flags):
  244.         rec = self.dbc.get(flags)
  245.         return self._extract(rec)
  246.  
  247.     def get_2(self, key, flags):
  248.         rec = self.dbc.get(key, flags)
  249.         return self._extract(rec)
  250.  
  251.     def get_3(self, key, value, flags):
  252.         data = cPickle.dumps(value, self.binary)
  253.         rec = self.dbc.get(key, flags)
  254.         return self._extract(rec)
  255.  
  256.  
  257.     def current(self, flags=0): return self.get_1(flags|db.DB_CURRENT)
  258.     def first(self, flags=0): return self.get_1(flags|db.DB_FIRST)
  259.     def last(self, flags=0): return self.get_1(flags|db.DB_LAST)
  260.     def next(self, flags=0): return self.get_1(flags|db.DB_NEXT)
  261.     def prev(self, flags=0): return self.get_1(flags|db.DB_PREV)
  262.     def consume(self, flags=0): return self.get_1(flags|db.DB_CONSUME)
  263.     def next_dup(self, flags=0): return self.get_1(flags|db.DB_NEXT_DUP)
  264.     def next_nodup(self, flags=0): return self.get_1(flags|db.DB_NEXT_NODUP)
  265.     def prev_nodup(self, flags=0): return self.get_1(flags|db.DB_PREV_NODUP)
  266.  
  267.  
  268.     def get_both(self, key, value, flags=0):
  269.         data = cPickle.dumps(value, self.binary)
  270.         rec = self.dbc.get_both(key, flags)
  271.         return self._extract(rec)
  272.  
  273.  
  274.     def set(self, key, flags=0):
  275.         rec = self.dbc.set(key, flags)
  276.         return self._extract(rec)
  277.  
  278.     def set_range(self, key, flags=0):
  279.         rec = self.dbc.set_range(key, flags)
  280.         return self._extract(rec)
  281.  
  282.     def set_recno(self, recno, flags=0):
  283.         rec = self.dbc.set_recno(recno, flags)
  284.         return self._extract(rec)
  285.  
  286.     set_both = get_both
  287.  
  288.     def _extract(self, rec):
  289.         if rec is None:
  290.             return None
  291.         else:
  292.             key, data = rec
  293.             return key, cPickle.loads(data)
  294.  
  295.     #----------------------------------------------
  296.     # Methods allowed to pass-through to self.dbc
  297.     #
  298.     # close, count, delete, get_recno, join_item
  299.  
  300.  
  301. #---------------------------------------------------------------------------
  302.